<!--
 * @Descripttion: 表格选择器组件
 * @version: 1.4
 * @Author: sakuya+tcy
 * @Date: 2021年6月10日10:04:07
 * @LastEditors: sakuya+tcy
 * @LastEditTime: 2023年8月2日21:50:36
-->
<template>
  <div class="el-input-group">
    <el-select ref="select" :style="{ width: inputWidth + 'px' }" v-model="defaultValue" :size="size" :limit="limit"
      :loading="loading" :clearable="clearable" :multiple="multiple" :collapse-tags="collapseTags"
      :max-collapse-tags="maxCollapseTags" :collapse-tags-tooltip="collapseTagsTooltip" :filterable="filterable"
      :filter-method="filterMethod" :placeholder="placeholder" :disabled="disabled" @remove-tag="removeTag"
      @clear="clear" @visible-change="visibleChange" class="tableselect">
      <template #empty>
        <div class="sc-table-select__table" :style="{ width: tableWidth + 'px' }" v-loading="loading">
          <div class="sc-table-select__header" v-if="formConfig">
            <div style="display: flex; margin-bottom: 10px">
              <el-checkbox @change="changeFuzzyQuery" v-model="fuzzyQuery">模糊</el-checkbox>
              <el-button type="primary" @click="formSubmit" style="margin-left: 10px">查 询</el-button>
            </div>
            <sc-form ref="formRef" :config="formConfig" v-model="formData" :modelValue="formData"
              @keyup.enter="search"></sc-form>
            <!-- <slot name="header" :form="formData" :submit="formSubmit"></slot> -->
          </div>
          <el-table ref="table" :data="tableData" :height="245" :highlight-current-row="!multiple" :lazy="lazy"
            :load="load" @row-click="click" row-key="id"
            :tree-props="{ children: 'children', hasChildren: 'hasChildren' }" @select="select" @select-all="selectAll"
            @row-dblclick="dblclick">
            <el-table-column v-if="multiple" type="selection" width="45"></el-table-column>
            <template v-for="(item, index) in tableConfig" :key="index">
              <el-table-column v-if="
                item.template &&
                item.template.nodes &&
                item.template.nodes[0].component == 'image'
              " :label="item.label" :width="flexWidth(item, tableData)">
                <template #default="scope">
                  <el-image :src="scope.row[item.prop]" preview-teleported></el-image>
                </template>
              </el-table-column>
              <el-table-column v-else-if="
                item.template &&
                item.template.nodes &&
                item.template.nodes[0].component == 'switch'
              " :label="item.label" :width="flexWidth(item, tableData)">
                <template #default="scope">
                  <el-switch disabled v-model="scope.row[item.prop]" :active-value="item.template.nodes[0].activeValue"
                    :inactive-value="item.template.nodes[0].inactiveValue" />
                </template>
              </el-table-column>
              <el-table-column v-else :prop="item.prop" :label="item.label" :width="flexWidth(item, tableData)" />
            </template>
            <slot></slot>
          </el-table>
          <div class="sc-table-select__page">
            <el-pagination small background layout="total,prev, pager, next" :total="total" :page-size="pageSize"
              v-model:currentPage="currentPage" @current-change="reload"></el-pagination>
          </div>
        </div>
      </template>
    </el-select>
    <el-button class="el-input-group__append" @click="showdialog" :icon="Search" />
  </div>
  <el-dialog v-model="dialogVisible" title="选择对话框" width="60%" append-to-body @close="dialogClose">
    <div v-if="formConfig" style="display: flex; margin-bottom: 10px">
      <el-checkbox @change="changeFuzzyQuery" v-model="fuzzyQuery">模糊</el-checkbox>
      <el-button type="primary" @click="formSubmit" style="margin-left: 10px">查 询</el-button>
    </div>
    <sc-form v-if="formConfig" ref="formRef" :config="formConfig" v-model="formData" :modelValue="formData"
      style="margin-bottom: 5px" @keyup.enter="search"></sc-form>
    <el-table ref="table" :height="350" :data="tableData" :highlight-current-row="!multiple" :lazy="lazy" :load="load"
      @row-click="click" row-key="id" :tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
      @select="select" @select-all="selectAll" @row-dblclick="dblclick">
      <el-table-column v-if="multiple" type="selection" width="45"></el-table-column>
      <template v-for="(item, index) in tableConfig" :key="index">
        <el-table-column v-if="
          item.template &&
          item.template.nodes &&
          item.template.nodes[0].component == 'image'
        " :label="item.label" :width="flexWidth(item, tableData)">
          <template #default="scope">
            <el-image :src="scope.row[item.prop]" preview-teleported></el-image>
          </template>
        </el-table-column>
        <el-table-column v-else-if="
          item.template &&
          item.template.nodes &&
          item.template.nodes[0].component == 'switch'
        " :label="item.label" :width="flexWidth(item, tableData)">
          <template #default="scope">
            <el-switch v-model="scope.row[item.prop]" :active-value="item.template.nodes[0].activeValue"
              :inactive-value="item.template.nodes[0].inactiveValue" />
          </template>
        </el-table-column>
        <el-table-column v-else :prop="item.prop" :label="item.label" :width="flexWidth(item, tableData)" />
      </template>
      <slot></slot>
    </el-table>
    <div class="sc-table-select__page">
      <el-pagination small background layout="total,prev, pager, next" :total="total" :page-size="pageSize"
        v-model:currentPage="currentPage" @current-change="reload"></el-pagination>
    </div>
  </el-dialog>
</template>
<script setup>
import { Search } from "@element-plus/icons-vue";
</script>
<script>
import config from "@/config/tableSelect";
import Api from "@/api/model/system";
import { ElNotification } from "element-plus";
import { deepClone } from "@/utils/arr";
export default {
  props: {
    modelValue: null,
    defaultSelected: { type: String, default: "" },
    defaultCurrent: { type: Array, default:()=> [] },
    apiObj: { type: Object, default: () => { } },
    fileName: { type: String, default: "" },
    params: { type: Object, default: () => { } },
    placeholder: { type: String, default: "请选择" },
    size: { type: String, default: "default" },
    clearable: { type: Boolean, default: true },
    multiple: { type: Boolean, default: false },
    filterable: { type: Boolean, default: true },
    collapseTags: { type: Boolean, default: true },
    collapseTagsTooltip: { type: Boolean, default: false },
    disabled: { type: Boolean, default: false },
    tableWidth: { type: Number, default: 800 },
    mode: { type: String, default: "dialog" },
    props: { type: Object, default: () => { } }, //显示label和绑定value值（也就是数据的唯一标识）
    limit: { type: Number, default: 99 },
    maxCollapseTags: { type: Number, default: 1 },
    inputWidth: { type: Number, default: 200 },
    mapping: { type: Array, default: () => [] }, //映射替换
    injectionKey: { type: String, default: "" }, //传给后台的标识用于查询相关数据
    initForm: { type: Object, default: () => { } }, //初始化条件
  },
  data() {
    return {
      loading: false,
      keyword: null,
      defaultValue: [],
      tableData: [],
      tableConfig: [],
      mapTableConfig: [],
      selectedLabel: "",
      currentLabel: [],
      pageSize: config.pageSize,
      total: 0,
      currentPage: 1,
      defaultProps: {
        label: config.props.label,
        value: config.props.value,
        page: config.request.page,
        pageSize: config.request.pageSize,
        keyword: config.request.keyword,
      },
      formConfig: {},
      formData: {},
      dialogVisible: false,
      fuzzyQuery: true,
      lazy: false,
      remoteSearchQuery: "",
    };
  },
  computed: {},
  watch: {
    modelValue: {
      handler() {
        this.defaultValue = JSON.parse(JSON.stringify(this.modelValue || []));
        this.autoCurrentLabel();
      },
      deep: true,
    },
    defaultSelected: {
      handler() {
        if (this.defaultSelected) {
          this.selectedLabel = this.defaultSelected;
          this.InitCurrentLabel();
        }
      },
      immediate: true,
    },
    defaultCurrent: {
      handler() {
        this.currentLabel = this.defaultCurrent;
        this.InitCurrentLabel();
      },
    },
  },
  mounted() {
    //
    this.defaultProps = Object.assign(this.defaultProps, this.props);
    this.defaultValue = JSON.parse(JSON.stringify(this.modelValue || []));
    if (this.selectedLabel) {
      this.InitCurrentLabel();
    } else {
      this.autoCurrentLabel();
    }
    if (this.initForm) {
      Object.assign(this.formData, this.initForm);
    }
    this.mapTableConfig = this.mapping.map((ele) => {
      return ele.label;
    });
  },
  methods: {
    flexWidth(item, tableData, num = 0) {
      if (item.flexColumnWidth == false || tableData.length == 0) {
        // 表格没数据不做处理
        if (item.width) {
          return item.width;
        }
        return;
      }
      let flexWidth = 0; // 初始化表格列宽
      let columnContent = ""; // 占位最宽的内容
      let canvas = document.createElement("canvas");
      let context = canvas.getContext("2d");
      context.font = "14px Microsoft YaHei";
      if (item.prop === "" && item.title) {
        // 标题长内容少的，取标题的值,
        columnContent = item.title;
      } else {
        // 获取该列中占位最宽的内容
        let index = 0;
        for (let i = 0; i < tableData.length; i++) {
          const now_temp = tableData[i][item.prop] + "";
          const max_temp = tableData[index][item.prop] + "";
          const now_temp_w = context.measureText(now_temp).width;
          const max_temp_w = context.measureText(max_temp).width;
          if (now_temp_w > max_temp_w) {
            index = i;
          }
        }
        columnContent = tableData[index][item.prop];

        // 比较占位最宽的值跟标题、标题为空的留出四个位置
        const column_w = context.measureText(columnContent).width;
        const title_w = context.measureText(item.title).width;
        if (column_w < title_w) {
          columnContent = item.title || "占位符呀";
        }
      }
      // 计算最宽内容的列宽
      let width = context.measureText(columnContent);
      flexWidth = width.width + 40 + num;
      return flexWidth;
    },
    //表格显示隐藏回调
    visibleChange(visible) {
      if (visible) {
        this.currentPage = 1;
        this.keyword = null;
        // this.formData = {};
        this.getInit();
        this.getData();
      } else {
        this.autoCurrentLabel();
      }
    },
    showdialog() {
      if (this.mode == "dialog") {
        this.$refs.select.blur();
        this.dialogVisible = true;
        this.getInit();
        this.getData();
      }
      if (this.mode == "select") {
        return;
      }
    },
    dialogClose() {
      this.$emit("closeUpdate", this.defaultValue);
    },
    changeFuzzyQuery(val) {
      this.fuzzyQuery = val;
    },
    search(e) {
      if (e.keyCode == 13) {
        this.getData();
      }
    },
    //获取表格数据
    async getData() {
      this.tableConfig = [];
      this.loading = true;
      var reqData = {
        fileName: this.fileName,
        pageSize: this.pageSize,
        pageNo: this.currentPage, //1
        fieldMap: this.formData,
        fuzzyQuery: this.fuzzyQuery,
        injectionConditionKey: this.injectionKey,
      };
      Object.assign(reqData);
      let res;
      if (this.apiObj) {
        res = await this.apiObj.post(reqData);
      } else {
        res = await Api.select.query.post(reqData);
      }

      if (res.code == 200) {
        var parseData = config.parseData(res);
        // this.tableData = parseData.data;
        this.total = parseData.rows;
        parseData.config.forEach((item) => {
          if (this.mapping.length > 0) {
            this.mapping.forEach((ele) => {
              if (ele.value == item.prop) {
                item.prop = ele.label;
              }
            });
            this.tableConfig.push(item);
          } else {
            this.tableConfig.push(item);
          }
        });
        this.tableData = parseData.data.map((item) => {
          if (this.mapping.length > 0) {
            this.mapping.forEach((ele) => {
              if (ele.label !== ele.value) {
                item[ele.label] = item[ele.value];
                delete item[ele.value];
              }
            });
            return item;
          } else {
            return item;
          }
        });
      }
      this.loading = false;
      //表格默认赋值
      this.$nextTick(() => {
        this.InitAssignment();
      });
    },
    InitAssignment(data) {
      if (this.multiple) {
        this.defaultValue.forEach((row) => {
          let setrow1 = [];
          if (data) {
            setrow1 = data.filter(
              (item) =>
                item[this.defaultProps.value] == row[this.defaultProps.value]
            );
          }
          var setrow2 = this.tableData.filter(
            (item) =>
              item[this.defaultProps.value] == row[this.defaultProps.value]
          );
          let setrow = setrow1.concat(setrow2);
          if (setrow.length > 0) {
            setrow.forEach(ele => {
              this.$refs.table.toggleRowSelection(ele, true);
            })
          }
        });
      } else {
        var setrow = this.tableData.filter(
          (item) =>
            item[this.defaultProps.value] ===
            this.defaultValue[this.defaultProps.value]
        );
        this.$refs.table.setCurrentRow(setrow[0]);
      }
      this.$refs.table.setScrollTop(0);
    },
    async getInit() {
      let params = {
        fileName: this.fileName,
      };
      let res = await Api.report.selectCompanyList.post(params);
      if (res.code == 200) {
        this.formConfig = res.bean.form;
        this.lazy = res.bean.table.lazy;
      }
    },
    //插糟表单提交
    formSubmit() {
      this.currentPage = 1;
      this.keyword = null;
      this.getData();
    },
    //分页刷新表格
    reload() {
      this.getData();
    },
    //自动模拟options赋值
    autoCurrentLabel() {
      this.$nextTick(() => {
        if (this.multiple) {
          this.$refs.select.selected.forEach((item) => {
            item.currentLabel = item.value[this.defaultProps.label];
          });
        } else {
          this.$refs.select.selectedLabel =
            this.defaultValue[this.defaultProps.label];
        }
      });
    },
    InitCurrentLabel() {
      this.$nextTick(() => {
        if (this.multiple) {
          this.$refs.select.selected.forEach((item, index) => {
            item.currentLabel = this.selectedLabel[index];
          });
        } else {
          this.$refs.select.selectedLabel = this.selectedLabel;
        }
      });
    },
    //表格勾选事件
    select(rows, row) {
      if (rows.length > this.limit) {
        ElNotification.info({ title: "超出最大限制" });
        this.$refs.table.toggleRowSelection(row, false);
      } else {
        var isSelect = rows.length && rows.indexOf(row) !== -1;
        if (isSelect) {
          this.defaultValue.push(row);
        } else {
          this.defaultValue.splice(
            this.defaultValue.findIndex(
              (item) =>
                item[this.defaultProps.value] == row[this.defaultProps.value]
            ),
            1
          );
        }
        this.autoCurrentLabel();
        if (this.mapTableConfig.length > 0) {
          let data = this.defaultValue.map((ele) => {
            for (var key in ele) {
              if (!this.mapTableConfig.includes(key)) {
                delete ele[key];
              }
            }
            return ele;
          });
          this.$emit("update:modelValue", data);
          this.$emit("change", data);
        } else {
          this.$emit("update:modelValue", this.defaultValue);
          this.$emit("change", this.defaultValue);
        }
      }
    },
    //表格全选事件
    selectAll(rows) {
      if (rows.length > this.limit) {
        ElNotification.info({ title: "超出最大限制" });
        this.$refs.table.clearSelection();
        this.InitAssignment()//将原本勾选的重新勾选上
        return false;
      }
      var isAllSelect = rows.length > 0;
      if (isAllSelect) {
        rows.forEach((row) => {
          var isHas = this.defaultValue.find(
            (item) =>
              item[this.defaultProps.value] == row[this.defaultProps.value]
          );
          if (!isHas) {
            this.defaultValue.push(row);
          }
        });
      } else {
        this.tableData.forEach((row) => {
          var isHas = this.defaultValue.find(
            (item) =>
              item[this.defaultProps.value] == row[this.defaultProps.value]
          );
          if (isHas) {
            this.defaultValue.splice(
              this.defaultValue.findIndex(
                (item) =>
                  item[this.defaultProps.value] == row[this.defaultProps.value]
              ),
              1
            );
          }
        });
      }
      this.autoCurrentLabel();
      if (this.mapTableConfig.length > 0) {
        let data = this.defaultValue.map((ele) => {
          for (var key in ele) {
            if (!this.mapTableConfig.includes(key)) {
              delete ele[key];
            }
          }
          return ele;
        });
        this.$emit("update:modelValue", data);
        this.$emit("change", data);
      } else {
        this.$emit("update:modelValue", this.defaultValue);
        this.$emit("change", this.defaultValue);
      }
    },
    click(row) {
      if (this.multiple) {
        //处理多选点击行
        return;
      } else {
        this.defaultValue = row;
        let data = JSON.parse(JSON.stringify(row));
        this.$refs.select.blur();
        this.autoCurrentLabel();
        for (var key in data) {
          if (this.mapTableConfig.length > 0) {
            if (!this.mapTableConfig.includes(key)) {
              delete data[key];
            }
          }
        }
        this.$emit("update:modelValue", data);
        this.$emit("change", data);
      }
    },
    dblclick() {
      this.dialogVisible = false;
    },
    //tags删除后回调
    removeTag(tag) {
      var row = this.findRowByKey(tag[this.defaultProps.value]);
      this.$refs.table.toggleRowSelection(row, false);
      this.$emit("update:modelValue", this.defaultValue);
      this.$emit("change", this.defaultValue);
    },
    //清空后的回调
    clear() {
      this.$emit("update:modelValue", this.defaultValue);
      this.$emit("change", this.defaultValue);
    },
    // 关键值查询表格数据行
    findRowByKey(value) {
      return this.tableData.find(
        (item) => item[this.defaultProps.value] === value
      );
    },
    filterMethod(keyword) {
      this.formData[this.props.label] = keyword;
      this.getData();
    },
    async load(row, treeNode, resolve) {
      let params = {
        parentId: row.id,
        fileName: this.fileName,
      };
      let res = await Api.select.query.post(params);
      let reportData;
      reportData = res.reportData.map((item) => {
        if (this.mapping.length > 0) {
          this.mapping.forEach((ele) => {
            item[ele.label] = item[ele.value];
            delete item[ele.value];
          });
          return item;
        } else {
          return item;
        }
      });
      this.$nextTick(() => {
        this.InitAssignment(reportData);
      });
    },
    // 触发select隐藏
    blur() {
      this.$refs.select.blur();
    },
    // 触发select显示
    focus() {
      this.$refs.select.focus();
    },
  },
};
</script>

<style lang="scss" scoped>
.sc-table-select__table {
  padding: 12px;
}

.sc-table-select__page {
  padding-top: 12px;
}

.tableselect {
  :deep(.el-input__wrapper) {
    padding-right: 1px;
    border-top-right-radius: 0;
    border-bottom-right-radius: 0;
  }

  // :deep(.el-select__caret) {
  // 	transform: rotateZ(0deg) !important;
  // 	margin-left: 12px;
  // }

  // :deep(.el-input__suffix) {
  // 	background-color: #f6f6f6;
  // 	width: 40px;
  // }
}

.icon {
  :deep(.el-input__wrapper) {
    padding-right: 1px;
    padding-left: 1px;
  }
}
</style>
